home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* DATABOSS MODULE: DB_TREE.C */
- /****************************************************************************/
-
- #include "db_lsc.h"
-
- #include <dos.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <share.h>
- #include <io.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #ifdef __TURBOC__
- #include <conio.h>
- #else
- #include <graph.h>
- #include <sys\types.h>
- #endif
- #include <sys\stat.h>
- #include "db_types.h"
- #include "db_conio.h"
- #include "db_dos.h"
- #include "db_heap.h"
- #include "db_key.h"
- #include "db_tree.h"
-
- /********************** GLOBAL INITIALIZED VARIABLES **********************/
-
- bool ignoresizediff = False;
- bool multiuser = False;
- bool flush_df = False;
- bool flush_if = False;
-
- int createaccess = 0x00;
- int openaccess = 0x02;
- int shareopenaccess = 0x42;
-
- /**************************** GLOBAL VARIABLES ****************************/
-
- byte errstatus;
- word btstatus;
- bool ok;
- bool lockget;
- btrecordbufptr btrecbuf;
- btpagestackptr btpagestk;
- btpagemapptr btpgmap;
- backdoor shutdown;
- bool recursive;
- int retries;
- int idx_retries;
- int _loop_count;
-
- /*************************** INTERNAL VARIABLES ***************************/
-
- static indexfile *dk_idxf; /* db_deletekey local global variables */
- static long *dk_datarecnum;
- static void *dk_prockey;
- static bool dk_pagetoosmall;
-
- static indexfile *ak_idxf; /* db_addkey local global variables */
- static long *ak_datarecnum;
- static void *ak_prockey;
- static bool ak_passup;
- static btitem ak_procitem1,ak_procitem2;
- static btpageptr ak_pageptr1,ak_pageptr2;
- static int ak_c,ak_k,ak_l;
- static long ak_prpgref2;
-
- static bool initialized = False;
-
- /************************* LOW LEVEL FILE FUNCTIONS ************************/
- int desiredhandle = 21; /* try to bypass 1st 20 handles */
-
- int DB_forcedup(int current, int desired)
- {
- int returnval;
- union REGS regs;
-
- returnval = -1;
- regs.h.ah = 0x46;
- regs.x.bx = current;
- regs.x.cx = desired;
- intdos(®s,®s);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = regs.x.ax;
- return(returnval);
- }
-
- int DB_close(int handle)
- {
- int returnval;
- union REGS regs;
-
- returnval = -1;
- regs.h.ah = 0x3E;
- regs.x.bx = handle;
- intdos(®s,®s);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = 0;
- return(returnval);
- }
-
- int DB_pushabove20(int handle)
- {
- int returnval;
-
- returnval = handle;
- if ((returnval > 0) && (returnval < 20)) {
- returnval = DB_forcedup(handle,desiredhandle);
- if (returnval != -1) {
- DB_close(handle);
- desiredhandle++;
- }
- else returnval = handle;
- }
- return(returnval);
- }
-
- int DB_creat(strptr fname, int attrib)
- {
- int returnval;
- union REGS regs;
- struct SREGS sregs;
-
- returnval = -1;
- regs.h.ah = 0x3C;
- sregs.ds = FP_SEG(fname);
- regs.x.dx = FP_OFF(fname);
- regs.x.cx = attrib;
- intdosx(®s,®s,&sregs);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = DB_pushabove20(regs.x.ax);
- return(returnval);
- }
-
- int DB_dup(int handle)
- {
- int returnval;
- union REGS regs;
-
- returnval = -1;
- regs.h.ah = 0x45;
- regs.x.bx = handle;
- intdos(®s,®s);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = regs.x.ax;
- return(returnval);
- }
-
- long DB_lseek(int handle, long offset, int fromwhere)
- {
- long returnval;
- union REGS regs;
- splitlong distance;
-
- returnval = -1L;
- regs.h.ah = 0x42;
- regs.h.al = fromwhere;
- distance.l = offset;
- regs.x.cx = distance.w.h;
- regs.x.dx = distance.w.l;
- regs.x.bx = handle;
- intdos(®s,®s);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else {
- distance.w.h = regs.x.dx;
- distance.w.l = regs.x.ax;
- returnval = distance.l;
- }
- return(returnval);
- }
-
- long DB_filelength(int handle)
- {
- long returnval, curposn;
-
- returnval = -1L;
- curposn = DB_lseek(handle, 0L, SEEK_CUR);
- if (curposn != -1L) {
- returnval = DB_lseek(handle, 0L, SEEK_END);
- if (returnval != -1L) curposn = DB_lseek(handle, curposn, SEEK_SET);
- }
- return(returnval);
- }
-
- int DB_open(strptr fname, int oflags)
- {
- int returnval;
- union REGS regs;
- struct SREGS sregs;
-
- returnval = -1;
- regs.h.ah = 0x3D;
- sregs.ds = FP_SEG(fname);
- regs.x.dx = FP_OFF(fname);
- regs.h.al = oflags;
- intdosx(®s,®s,&sregs);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = DB_pushabove20(regs.x.ax);
- return(returnval);
- }
-
- int DB_read(int handle, void *buf, unsigned len)
- {
- int returnval;
- union REGS regs;
- struct SREGS sregs;
-
- returnval = -1;
- regs.h.ah = 0x3F;
- sregs.ds = FP_SEG(buf);
- regs.x.dx = FP_OFF(buf);
- regs.x.cx = len;
- regs.x.bx = handle;
- intdosx(®s,®s,&sregs);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = regs.x.ax;
- return(returnval);
- }
-
- int DB_write(int handle, void *buf, unsigned len)
- {
- int returnval;
- union REGS regs;
- struct SREGS sregs;
-
- returnval = -1;
- regs.h.ah = 0x40;
- sregs.ds = FP_SEG(buf);
- regs.x.dx = FP_OFF(buf);
- regs.x.cx = len;
- regs.x.bx = handle;
- intdosx(®s,®s,&sregs);
- if (regs.x.cflag)
- errno = regs.x.ax;
- else
- returnval = regs.x.ax;
- /*************************** DISK FULL ERROR ?? ****************************
- Disk IO errors are trapped by the calling routines ie. "putrec".
- Disk Full is indicated by a return value less than "len" when it is not
- returning an error condition of "-1".
-
- if ((returnval != -1) && (returnval != len)) {
- returnval = -1;
- errno = 101;
- }
- ***************************************************************************/
- return(returnval);
- }
- /*
- int DB_close(int handle) {return (_close(handle));}
- int DB_creat(strptr fname, int attrib) {return (_creat(fname,attrib));}
- int DB_dup(int handle) {return(dup(handle));}
- long DB_lseek(int handle, long offset, int fromwhere) {return(lseek(handle,offset,fromwhere));}
- long DB_filelength(int handle) {return(filelength(handle));}
- int DB_open(strptr fname, int oflags) {return(_open(fname,oflags));}
- int DB_read(int handle, void *buf, unsigned len) {return(read(handle,buf,len));}
- int DB_write(int handle, void *buf, unsigned len) {return(write(handle,buf,len));}
- */
-
- /***************************** IMPLEMENTATION *****************************/
-
- strptr ioerrstr(strptr sout, int n)
- {
- strptr m;
-
- switch (n) {
- case 1 : m = "Invalid DOS function code"; break;
- case 2 : m = "File not found"; break;
- case 3 : m = "Path not found"; break;
- case 4 : m = "Too many open files"; break;
- case 5 : m = "File access denied"; break;
- case 6 : m = "Invalid file handle"; break;
- case 8 : m = "Not enough memory"; break;
- case 12 : m = "Invalid file access code"; break;
- case 15 : m = "Invalid drive number"; break;
- case 16 : m = "Cannot remove current directory"; break;
- case 17 : m = "Cannot rename across drives"; break;
- case 100 : m = "Disk read error"; break;
- case 101 : m = "Disk write error"; break;
- case 102 : m = "File not assigned"; break;
- case 103 : m = "File not open"; break;
- case 104 : m = "File not open for input"; break;
- case 105 : m = "File not open for output"; break;
- case 106 : m = "Invalid numeric format"; break;
- case 200 : m = "Division by zero"; break;
- case 201 : m = "Range check error"; break;
- case 202 : m = "Stack overflow error"; break;
- case 203 : m = "Heap overflow error"; break;
- case 204 : m = "Invalid pointer operation"; break;
- case 1000 : m = "Record size is greater than max record size"; break;
- case 1001 : m = "Record size is too small"; break;
- case 1002 : m = "Key length is greater than max key length"; break;
- case 1003 : m = "Data File created with different record size"; break;
- case 1004 : m = "Index File created with different key or page size"; break;
- case 1005 : m = "Not enough memory for page stack"; break;
- case 2000 : m = "Illegal attempt to alter STATUS record";
- default : m = "UnRecognized"; break;
- }
- return (strcpy(sout,m));
- }
-
- bool outputerror(strptr filenm, long r)
- {
- int errorfile;
- errorstring emsg;
- time_t t;
-
- errorfile = _creat(ErrFileNm,createaccess);
- if (errorfile == -1) return (False);
- _close(errorfile);
- errorfile = open(ErrFileNm,O_TEXT | O_RDWR, S_IREAD | S_IWRITE);
- if (errorfile == -1) return (False);
- t = time(NULL);
- sprintf(emsg,"Database I/O Fatal Error generated at %s\r\n",ctime(&t));
- write(errorfile,emsg,strlen(emsg));
- sprintf(emsg,"Error %d %s\r\n\r\n",btstatus,ioerrstr(emsg,btstatus));
- write(errorfile,emsg,strlen(emsg));
- if (*filenm) {
- sprintf(emsg,"File: %s\r\nRecord: %ld\r\n",filenm,r);
- write(errorfile,emsg,strlen(emsg));
- }
- _close(errorfile);
- return (True);
- }
-
- void btcrash(strptr filenm, long r)
- {
- if (!((btstatus == 100) && multiuser)) {
- if (outputerror(filenm,r)) {
- }
- }
- errstatus = (byte) btstatus;
- }
-
- void btiocheck(datafile *datf, long r)
- {
- filename filenm;
-
- if (errstatus > 0) return;
- if (btstatus != 0) {
- strcpy(filenm,datf -> f.name);
- btcrash(filenm,r);
- }
- }
-
- word duphandle(word handle)
- {
- int h;
-
- h = DB_dup(handle);
- if (h < 0) btstatus = errno;
- return (h);
- }
-
- void db_closefilehandle(word handle)
- {
- if (DB_close(handle) != 0) getch();
- printf("Handle = %i Errno = %i",handle,errno);
- }
-
- void flushdosfile(word handle)
- {
- word clonehandle;
-
- if (errstatus > 0) return;
- clonehandle = duphandle(handle);
- if (btstatus == 0) DB_close(clonehandle);
- }
-
- void db_getlockedrec(datafile *datf, long r, void *buffer)
- {
- long *lbuffer;
- long fpos;
-
- if (errstatus > 0) return;
- lbuffer = buffer;
- *lbuffer++ = -100;
- fpos = (r * datf->itemsize) + 4;
- btstatus = (DB_lseek(datf->f.handle,fpos,SEEK_SET) == -1) ? errno : 0;
- if (btstatus != 0)
- btstatus = (DB_lseek(datf->f.handle,fpos,SEEK_SET) == -1) ? errno : 0;
- btiocheck(datf,r);
- if (errstatus > 0) return;
- DB_read(datf->f.handle,(void *)lbuffer,(word) datf->itemsize-4);
- btiocheck(datf,r);
- lockget = True;
- }
-
- void db_getrec(datafile *datf, long r, void *buffer)
- {
- word bytesread;
-
- if (errstatus > 0) return;
- btstatus = (DB_lseek(datf->f.handle,r*datf->f.recsize,SEEK_SET) == -1) ? errno : 0;
- if (btstatus != 0)
- btstatus = (DB_lseek(datf->f.handle,r*datf->f.recsize,SEEK_SET)==-1) ? errno : 0;
- if (multiuser && (btstatus != 0)) btstatus = 100;
- btiocheck(datf,r);
- if (errstatus > 0) return;
- bytesread = DB_read(datf->f.handle,buffer,datf->f.recsize);
- if (bytesread != datf->f.recsize) btstatus = 100;
- btiocheck(datf,r);
- }
-
- void db_putrec(datafile *datf, long r, void *buffer)
- {
- word byteswritten;
-
- if (errstatus > 0) return;
- btstatus = (DB_lseek(datf->f.handle,r*datf->f.recsize,SEEK_SET) == -1) ? errno : 0;
- if (btstatus != 0)
- btstatus = (DB_lseek(datf->f.handle,r*datf->f.recsize,SEEK_SET)==-1) ? errno : 0;
- if (multiuser && (btstatus != 0)) btstatus = 100;
- btiocheck(datf,r);
- if (errstatus > 0) return;
- byteswritten = DB_write(datf->f.handle,buffer,datf->f.recsize);
- if (byteswritten != datf->f.recsize) btstatus = 101;
- btiocheck(datf,r);
- }
-
- void readheader(datafile *datf)
- {
- if (errstatus > 0) return;
- db_getrec(datf,0L,btrecbuf);
- if (errstatus > 0) return;
- memmove(&datf->firstfree,btrecbuf,DB_fhs);
- datf->numrec = DB_filelength(datf->f.handle)/datf->f.recsize;
- }
-
- bool vfydtahdr(datafile *datf)
- {
- if (multiuser && (errstatus == 0)) readheader(datf);
- return ((bool) (errstatus == 0));
- }
-
- bool vfyidxhdr(indexfile *idxf)
- {
- if (multiuser && (errstatus == 0)) {
- readheader(&idxf->dataf);
- idxf->rr = idxf->dataf.int1;
- }
- return ((bool) (errstatus == 0));
- }
-
- void writeheader(datafile *datf, word reclen)
- {
- if (errstatus > 0) return;
- memset(btrecbuf,0,sizeof(*btrecbuf));
- datf->firstfree = -1;
- datf->itemsize = reclen;
- memmove(btrecbuf,&datf->firstfree,DB_fhs);
- db_putrec(datf,0L,btrecbuf);
- btiocheck(datf,0L);
- if (errstatus > 0) return;
- datf->numrec = 1;
- ok = True;
- }
-
- void db_makefile(datafile *datf, strptr fname, word reclen)
- {
- if (errstatus > 0) return;
- btstatus = 0;
- memset(datf,0,sizeof(*datf));
- datf->f.handle = DB_creat(fname,createaccess);
- datf->f.recsize = reclen;
- strcpy(datf->f.name,fname);
- ok = (bool) (datf->f.handle != -1);
- if (ok) {
- if (reclen > DB_mxdrs) btstatus = RecTooLarge;
- if (reclen < DB_mdrs) btstatus = RecTooSmall;
- btiocheck(datf,0L);
- writeheader(datf,reclen);
- if (errstatus > 0) return;
- }
- }
-
- void db_openfile(datafile *datf, strptr fname, word reclen)
- {
- if (errstatus > 0) return;
- memset(datf,0,sizeof(*datf));
- if (multiuser)
- datf->f.handle = DB_open(fname, shareopenaccess);
- else
- datf->f.handle = DB_open(fname,openaccess);
- datf->f.recsize = reclen;
- strcpy(datf->f.name,fname);
- btstatus = (datf->f.handle != -1) ? 0 : errno;
- ok = (bool) (btstatus == 0);
- if (ok) {
- if (reclen > DB_mxdrs) btstatus = RecTooLarge;
- if (reclen < DB_mdrs) btstatus = RecTooSmall;
- btiocheck(datf,0L);
- readheader(datf);
- if (errstatus > 0) return;
- if (reclen != (word) datf->itemsize) {
- if (ignoresizediff)
- datf->itemsize = reclen;
- else {
- btstatus = RecSizeMismatch;
- btiocheck(datf,0L);
- }
- }
- }
- }
-
- void putfileheader(datafile *datf)
- {
- if (errstatus > 0) return;
- memset(btrecbuf,0,sizeof(*btrecbuf));
- datf->int2 = datf->numrec;
- datf->itemsize = datf->f.recsize;
- memmove(btrecbuf,&datf->firstfree,DB_fhs);
- db_putrec(datf,0L,btrecbuf);
- }
-
- void db_closefile(datafile *datf)
- {
- if (!vfydtahdr(datf)) return;
- putfileheader(datf);
- if (errstatus > 0) return;
- btstatus = (DB_close(datf->f.handle) == 0) ? 0 : errno;
- btiocheck(datf,0L);
- }
-
- void db_flushfile(datafile *datf)
- {
- if (!vfydtahdr(datf)) return;
- putfileheader(datf);
- flushdosfile(datf->f.handle);
- btiocheck(datf,0L);
- }
-
- void newrec(datafile *datf, long *r)
- {
- if (errstatus > 0) return;
- if (datf->firstfree == -1)
- *r = datf->numrec++;
- else {
- *r = datf->firstfree;
- db_getrec(datf,*r,btrecbuf);
- if (errstatus > 0) return;
- datf->firstfree = btrecbuf->i;
- datf->numberfree--;
- }
- }
-
- void db_addrec(datafile *datf, long *r, void *buffer)
- {
- if (!vfydtahdr(datf)) return;
- newrec(datf,r);
- db_putrec(datf,*r,buffer);
- if (errstatus > 0) return;
- if (multiuser) putfileheader(datf);
- }
-
- void db_deleterec(datafile *datf, long r)
- {
- if (!vfydtahdr(datf)) return;
- btrecbuf->i = datf->firstfree;
- db_putrec(datf,r,btrecbuf);
- if (errstatus > 0) return;
- datf->firstfree = r;
- datf->numberfree++;
- if (multiuser) putfileheader(datf);
- }
-
- long db_filelen(datafile *datf)
- {
- return ((vfydtahdr(datf)) ? datf->numrec : 0);
- }
-
- long db_usedrecs(datafile *datf)
- {
- return ((vfydtahdr(datf)) ? datf->numrec - datf->numberfree - 1 : 0);
- }
-
- void db_initindex(void)
- /* done by unit initialization they reckon */
- {
- }
-
- void btpack(btpage *page, byte keyl)
- {
- byteptr p;
- int isize;
- int i;
-
- if (keyl != DB_Klen) {
- p = ((byteptr) page) + PageOverhead;
- isize = keyl + ItemOverhead;
- for (i = 0; i < DB_ps ; i++)
- memmove(p+(i*isize),&page->itemarray[i],isize);
- }
- }
-
- void btunpack(btpage *page, byte keyl)
- {
- byteptr p;
- int isize;
- int i;
-
- if (keyl != DB_Klen) {
- p = ((byteptr) page) + PageOverhead;
- isize = keyl + ItemOverhead;
- for (i = DB_ps-1 ; i >= 0 ; i--)
- memmove(&page->itemarray[i],p+(i*isize),isize);
- }
- }
-
- void db_makeindex(indexfile *idxf, strptr fname, byte keylen, byte s)
- {
- word k;
-
- if (errstatus > 0) return;
- memset(idxf,0,sizeof(*idxf));
- k = (keylen + ItemOverhead) * DB_ps + PageOverhead;
- idxf->dataf.f.handle = DB_creat(fname,createaccess);
- idxf->dataf.f.recsize = k;
- strcpy(idxf->dataf.f.name,fname);
- btstatus = (idxf->dataf.f.handle != -1) ? 0 : errno;
- if (keylen > DB_Klen)
- btstatus = KeyTooLarge;
- btiocheck(&idxf->dataf,0L);
- writeheader(&idxf->dataf,k);
- if (errstatus > 0)
- return;
- idxf->allowduplkeys = (bool) (s != NoDuplicates);
- idxf->keyl = keylen;
- }
-
- void db_openindex(indexfile *idxf, strptr fname, byte keylen, byte s)
- {
- word k;
-
- if (errstatus > 0) return;
- memset(idxf,0,sizeof(*idxf));
- k = (keylen + ItemOverhead) * DB_ps + PageOverhead;
- if (multiuser)
- idxf->dataf.f.handle = DB_open(fname, shareopenaccess);
- else
- idxf->dataf.f.handle = DB_open(fname, openaccess);
- idxf->dataf.f.recsize = k;
- strcpy(idxf->dataf.f.name,fname);
- btstatus = (idxf->dataf.f.handle != -1) ? 0 : errno;
- ok = (bool) (btstatus == 0);
- if (ok) {
- if (keylen > DB_Klen) {
- btstatus = KeyTooLarge;
- btiocheck(&idxf->dataf,0L);
- if (errstatus > 0) return;
- }
- readheader(&idxf->dataf);
- if (errstatus > 0) return;
- if (k != (word) idxf->dataf.itemsize) {
- if (ignoresizediff)
- idxf->dataf.itemsize = k;
- else {
- btstatus = KeySizeMismatch;
- btiocheck(&idxf->dataf,0L);
- if (errstatus > 0) return;
- }
- }
- idxf->allowduplkeys = (bool) (s != NoDuplicates);
- idxf->keyl = keylen;
- idxf->rr = idxf->dataf.int1;
- idxf->pp = 0;
- }
- }
-
- void storeindexheader(indexfile *idxf)
- {
- int i;
- btstackrecptr btsrp;
-
- if (errstatus > 0) return;
- for (i = 1, btsrp = &(*btpagestk)[0]; i <= DB_pstack; i++, btsrp++) {
- if (btsrp->indexfptr == idxf) {
- btsrp->indexfptr = NULL;
- if (btsrp->updated) {
- btpack(&btsrp->page,idxf->keyl);
- db_putrec(&idxf->dataf,btsrp->pageref,&btsrp->page);
- if (errstatus > 0) return;
- btsrp->updated = False;
- }
- }
- }
- idxf->dataf.int1 = idxf->rr;
- }
-
- void db_closeindex(indexfile *idxf)
- {
- if (!vfyidxhdr(idxf)) return;
- storeindexheader(idxf);
- db_closefile(&idxf->dataf);
- }
-
- void db_flushindex(indexfile *idxf)
- {
- if (!vfyidxhdr(idxf)) return;
- storeindexheader(idxf);
- db_flushfile(&idxf->dataf);
- }
-
- void db_erasefile(datafile *datf)
- {
- db_closefile(datf);
- if (errstatus > 0) return;
- unlink(datf->f.name);
- }
-
- void db_eraseindex(indexfile *idxf)
- {
- db_closeindex(idxf);
- if (errstatus > 0) return;
- unlink(idxf->dataf.f.name);
- }
-
- void btlast(long i)
- {
- int j,k;
-
- j = 1;
- while (((*btpgmap)[j-1] != (word) i) && (j < DB_pstack)) j++;
- for (k = j ; k <= (DB_pstack-1) ; k++)
- (*btpgmap)[k-1] = (*btpgmap)[k];
- (*btpgmap)[DB_pstack-1] = (word) i;
- }
-
- void btgetpage(indexfile *idxf, long r, btpageptr *pgptr)
- {
- long i;
- bool found;
- btstackrecptr btsrp;
-
- if (errstatus > 0) return;
- i = 0;
- if (multiuser)
- found = False;
- else {
- do {
- i++;
- btsrp = &(*btpagestk)[(int) i-1];
- found = (bool) ((btsrp->indexfptr == idxf) && (btsrp->pageref == r));
- } while ((!found) && (i < DB_pstack));
- }
- if (!found) {
- i = (*btpgmap)[0];
- btsrp = &(*btpagestk)[(int) i-1];
- if (btsrp->updated) {
- btpack(&btsrp->page,btsrp->indexfptr->keyl);
- db_putrec(&btsrp->indexfptr->dataf,btsrp->pageref,&btsrp->page);
- if (errstatus > 0) return;
- }
- db_getrec(&idxf->dataf,r,&btsrp->page);
- if (errstatus > 0) return;
- btunpack(&btsrp->page,idxf->keyl);
- btsrp->indexfptr = idxf;
- btsrp->pageref = r;
- btsrp->updated = False;
- }
- btlast(i);
- *pgptr = &(*btpagestk)[(int) i-1].page;
- }
-
- void btnewpage(indexfile *idxf, long *r, btpageptr *pgptr)
- {
- long i;
- btstackrecptr btsrp;
-
- if (errstatus > 0) return;
- i = (*btpgmap)[0];
- btsrp = &(*btpagestk)[(int) i-1];
- if (btsrp->updated) {
- btpack(&btsrp->page,btsrp->indexfptr->keyl);
- db_putrec(&btsrp->indexfptr->dataf,btsrp->pageref,&btsrp->page);
- if (errstatus > 0) return;
- }
- newrec(&idxf->dataf,r);
- if (errstatus > 0) return;
- btsrp->indexfptr = idxf;
- btsrp->pageref = *r;
- btsrp->updated = False;
- btlast(i);
- *pgptr = &(*btpagestk)[(int) i-1].page;
- }
-
- void btupdatepage(btpageptr pgptr)
- {
- btstackrecptr btsrp;
-
- if (errstatus > 0) return;
- btsrp = (btstackrecptr) pgptr;
- if (multiuser) {
- btpack(&btsrp->page,btsrp->indexfptr->keyl);
- db_putrec(&btsrp->indexfptr->dataf,btsrp->pageref,&btsrp->page);
- if (errstatus > 0) return;
- btunpack(&btsrp->page,btsrp->indexfptr->keyl);
- btsrp->indexfptr->dataf.int1 = btsrp->indexfptr->rr;
- putfileheader(&btsrp->indexfptr->dataf);
- }
- else
- btsrp->updated = True;
- }
-
- void btreturnpage(btpageptr *pgptr)
- {
- btstackrecptr btsrp;
-
- if (errstatus > 0) return;
- btsrp = (btstackrecptr) *pgptr;
- db_deleterec(&btsrp->indexfptr->dataf,btsrp->pageref);
- if (errstatus > 0) return;
- btsrp->indexfptr->dataf.int1 = btsrp->indexfptr->rr;
- putfileheader(&btsrp->indexfptr->dataf);
- btsrp->indexfptr = NULL;
- btsrp->updated = False;
- }
-
- void btxkey(void *k, byte keyl)
- {
- strptr s;
-
- s = k;
- if (strlen(s) > keyl) s[keyl] = '\0';
- }
-
- int btcompkeys(void *k1, void *k2, long dr1, long dr2, bool dup)
- {
- strptr s1,s2;
- int i;
-
- s1 = k1;
- s2 = k2;
- if (strcmp(s1,s2) == 0) {
- if ((!dup) || (dr1 == dr2))
- i = 0;
- else
- i = ((dr1+0x80000000L) > (dr2+0x80000000L)) ? 1 : -1;
- }
- else
- i = (strcmp(s1,s2) > 0) ? 1 : -1;
- return (i);
- }
-
- void db_clearkey(indexfile *idxf)
- {
- if (errstatus > 0) return;
- idxf->pp = 0;
- }
-
- void db_nextkey(indexfile *idxf,long *datarecnum, void *prockey)
- {
- long r;
- btpageptr pagptr;
- btsearchstepptr btssp;
- btitemptr btip;
-
- if (!vfyidxhdr(idxf)) return;
- if (idxf->pp == 0)
- r = idxf->rr;
- else {
- btssp = &idxf->path[(int) idxf->pp-1];
- btgetpage(idxf,btssp->pageref,&pagptr);
- if (errstatus) return;
- r = pagptr->itemarray[(int) btssp->itemarrindex-1].pageref;
- }
- while (r != 0) {
- (idxf->pp)++;
- btssp = &idxf->path[(int) idxf->pp-1];
- btssp->pageref = r;
- btssp->itemarrindex = 0;
- btgetpage(idxf,r,&pagptr);
- if (errstatus) return;
- r = pagptr->bckwpageref;
- }
- if (idxf->pp != 0) {
- btssp = &idxf->path[(int) idxf->pp-1];
- while ((idxf->pp > 1) && (btssp->itemarrindex == pagptr->itemsonpage)) {
- (idxf->pp)--;
- btssp--;
- btgetpage(idxf,btssp->pageref,&pagptr);
- if (errstatus) return;
- }
- if (btssp->itemarrindex < pagptr->itemsonpage) {
- (btssp->itemarrindex)++;
- btip = &pagptr->itemarray[(int) btssp->itemarrindex-1];
- strcpy(prockey,btip->key);
- *datarecnum = btip->dataref;
- }
- else
- idxf->pp = 0;
- }
- ok = (bool) (idxf->pp != 0);
- }
-
- void db_prevkey(indexfile *idxf,long *datarecnum, void *prockey)
- {
- long r;
- btpageptr pagptr;
- btsearchstepptr btssp;
- btitemptr btip;
-
- if (!vfyidxhdr(idxf)) return;
- if (idxf->pp == 0)
- r = idxf->rr;
- else {
- btssp = &idxf->path[(int) idxf->pp-1];
- btgetpage(idxf,btssp->pageref,&pagptr);
- if (errstatus) return;
- if (--(btssp->itemarrindex) == 0)
- r = pagptr->bckwpageref;
- else
- r = pagptr->itemarray[(int) btssp->itemarrindex-1].pageref;
- }
- while (r != 0) {
- btgetpage(idxf,r,&pagptr);
- if (errstatus) return;
- (idxf->pp)++;
- btssp = &idxf->path[(int) idxf->pp-1];
- btssp->pageref = r;
- btssp->itemarrindex = pagptr->itemsonpage;
- r = pagptr->itemarray[pagptr->itemsonpage-1].pageref;
- }
- if (idxf->pp != 0) {
- btssp = &idxf->path[(int) idxf->pp-1];
- while ((idxf->pp > 1) && (btssp->itemarrindex == 0)) {
- (idxf->pp)--;
- btssp--;
- btgetpage(idxf,btssp->pageref,&pagptr);
- if (errstatus) return;
- }
- if (btssp->itemarrindex > 0) {
- btip = &pagptr->itemarray[(int) btssp->itemarrindex-1];
- strcpy(prockey,btip->key);
- *datarecnum = btip->dataref;
- }
- else
- idxf->pp = 0;
- }
- ok = (bool) (idxf->pp !=0);
- }
-
- void btdb_findkey(indexfile *idxf,long *datarecnum, void *prockey)
- {
- long prpgref;
- int c,k,l,r;
- btpageptr pagptr;
- btsearchstepptr btssp;
-
- if (!vfyidxhdr(idxf)) return;
- btxkey(prockey,idxf->keyl);
- ok = False;
- idxf->pp = 0;
- prpgref = idxf->rr;
- while ((prpgref != 0) && !ok) {
- (idxf->pp)++;
- idxf->path[(int) idxf->pp-1].pageref = prpgref;
- btgetpage(idxf,prpgref,&pagptr);
- if (errstatus > 0) return;
- l = 1;
- r = pagptr->itemsonpage;
- do {
- k = (l + r)/2;
- c = btcompkeys(prockey,pagptr->itemarray[k-1].key,0L,
- pagptr->itemarray[k-1].dataref,idxf->allowduplkeys);
- if (c <= 0) r = k - 1;
- if (c >= 0) l = k + 1;
- } while (r >= l);
- if (l - r > 1) {
- *datarecnum = pagptr->itemarray[k-1].dataref;
- r = k;
- ok = True;
- }
- prpgref = (r==0)?pagptr->bckwpageref:pagptr->itemarray[r-1].pageref;
- idxf->path[(int) idxf->pp-1].itemarrindex = r;
- }
- if ((!ok) && (idxf->pp > 0)) {
- btssp = &idxf->path[(int) idxf->pp-1];
- while ((idxf->pp > 1) && (btssp->itemarrindex == 0)) {
- (idxf->pp)--;
- btssp--;
- }
- if (btssp->itemarrindex == 0) idxf->pp = 0;
- }
- }
-
- void db_findkey(indexfile *idxf,long *datarecnum, void *prockey)
- {
- btkeystr tempkey;
-
- btdb_findkey(idxf,datarecnum,prockey);
- if (errstatus > 0 ) return;
- if ((!ok) && (idxf->allowduplkeys)) {
- strcpy(tempkey,prockey);
- db_nextkey(idxf,datarecnum,prockey);
- if (errstatus > 0 ) return;
- ok = (bool) (ok && (strcmp(prockey,tempkey) == 0));
- }
- }
-
- void db_search(indexfile *idxf,long *datarecnum, void *prockey)
- {
- btdb_findkey(idxf,datarecnum,prockey);
- if (errstatus > 0 ) return;
- if (!ok) db_nextkey(idxf,datarecnum,prockey);
- }
-
- void ak_insert(long prpgref1, int *r)
- {
- int i;
-
- btgetpage(ak_idxf,prpgref1,&ak_pageptr1);
- if (errstatus > 0) return;
- if (ak_pageptr1->itemsonpage < DB_ps) {
- (ak_pageptr1->itemsonpage)++;
- for (i = ak_pageptr1->itemsonpage ; i >= *r+2 ; i--)
- ak_pageptr1->itemarray[i-1] = ak_pageptr1->itemarray[i-2];
- ak_pageptr1->itemarray[*r] = ak_procitem1;
- ak_passup = False;
- }
- else {
- btnewpage(ak_idxf,&ak_prpgref2,&ak_pageptr2);
- if (errstatus > 0) return;
- if (*r <= DB_ord) {
- if (*r == DB_ord)
- ak_procitem2 = ak_procitem1;
- else {
- ak_procitem2 = ak_pageptr1->itemarray[DB_ord-1];
- for (i = DB_ord; i >= *r + 2 ; i--)
- ak_pageptr1->itemarray[i-1] = ak_pageptr1->itemarray[i-2];
- ak_pageptr1->itemarray[*r] = ak_procitem1;
- }
- for (i = 1 ; i <= DB_ord ; i++)
- ak_pageptr2->itemarray[i-1]=ak_pageptr1->itemarray[i+DB_ord-1];
- }
- else {
- *r -= DB_ord;
- ak_procitem2 = ak_pageptr1->itemarray[DB_ord];
- for (i = 1 ; i <= *r - 1 ; i++)
- ak_pageptr2->itemarray[i-1]=ak_pageptr1->itemarray[i+DB_ord];
- ak_pageptr2->itemarray[*r-1] = ak_procitem1;
- for (i = *r + 1 ; i <= DB_ord ; i++)
- ak_pageptr2->itemarray[i-1]=ak_pageptr1->itemarray[i+DB_ord-1];
- }
- ak_pageptr1->itemsonpage = DB_ord;
- ak_pageptr2->itemsonpage = DB_ord;
- ak_pageptr2->bckwpageref = ak_procitem2.pageref;
- ak_procitem2.pageref = ak_prpgref2;
- ak_procitem1 = ak_procitem2;
- btupdatepage(ak_pageptr2);
- if (errstatus > 0) return;
- }
- btupdatepage(ak_pageptr1);
- }
-
- void ak_search(long prpgref1)
- {
- int r;
-
- if (errstatus > 0) return;
- if (prpgref1 == 0) {
- ak_passup = True;
- strcpy(ak_procitem1.key,ak_prockey);
- ak_procitem1.dataref = *ak_datarecnum;
- ak_procitem1.pageref = 0;
- }
- else {
- btgetpage(ak_idxf,prpgref1,&ak_pageptr1);
- if (errstatus > 0) return;
- ak_l = 1;
- r = ak_pageptr1->itemsonpage;
- do {
- ak_k = (ak_l + r)/2;
- ak_c = btcompkeys(ak_prockey,ak_pageptr1->itemarray[ak_k-1].key,
- *ak_datarecnum,
- ak_pageptr1->itemarray[ak_k-1].dataref,
- ak_idxf->allowduplkeys);
- if (ak_c <= 0) r = ak_k - 1;
- if (ak_c >= 0) ak_l = ak_k + 1;
- } while (r >= ak_l);
- if ((ak_l-r) > 1) {
- ok = False;
- ak_passup = False;
- }
- else {
- if (r == 0)
- ak_search(ak_pageptr1->bckwpageref);
- else
- ak_search(ak_pageptr1->itemarray[r-1].pageref);
- if (errstatus > 0) return;
- if (ak_passup) ak_insert(prpgref1,&r);
- }
- }
- }
-
- void db_addkey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- long prpgref1;
-
- if (!vfyidxhdr(idxf)) return;
- ak_idxf = idxf;
- ak_datarecnum = datarecnum;
- ak_prockey = prockey;
- btxkey(prockey,idxf->keyl);
- ok = True;
- ak_search(idxf->rr);
- if (errstatus > 0) return;
- if (ak_passup) {
- prpgref1 = idxf->rr;
- btnewpage(idxf,&idxf->rr,&ak_pageptr1);
- if (errstatus > 0) return;
- ak_pageptr1->itemsonpage = 1;
- ak_pageptr1->bckwpageref = prpgref1;
- ak_pageptr1->itemarray[0] = ak_procitem1;
- btupdatepage(ak_pageptr1);
- if (errstatus > 0) return;
- }
- idxf->pp = 0;
- }
-
- void dk_underflow(long prpgref, long prpgref2, int r)
- {
- int i,k,litem;
- long lpageref;
- btpageptr pagptr,pageptr2,l;
-
- btgetpage(dk_idxf,prpgref,&pagptr);
- btgetpage(dk_idxf,prpgref2,&pageptr2);
- if (errstatus > 0) return;
- if (r < pagptr->itemsonpage) {
- r++;
- lpageref = pagptr->itemarray[r-1].pageref;
- btgetpage(dk_idxf,lpageref,&l);
- if (errstatus > 0) return;
- k = (l->itemsonpage - DB_ord + 1)/2;
- pageptr2->itemarray[DB_ord-1] = pagptr->itemarray[r-1];
- pageptr2->itemarray[DB_ord-1].pageref = l->bckwpageref;
- if (k > 0) {
- for (i = 1 ; i <= k-1 ; i++)
- pageptr2->itemarray[i+DB_ord-1] = l->itemarray[i-1];
- pagptr->itemarray[r-1] = l->itemarray[k-1];
- pagptr->itemarray[r-1].pageref = lpageref;
- l->bckwpageref = l->itemarray[k-1].pageref;
- l->itemsonpage = l->itemsonpage - k;
- for (i = 1 ; i <= l->itemsonpage ; i++)
- l->itemarray[i-1] = l->itemarray[i+k-1];
- pageptr2->itemsonpage = (byte) (DB_ord - 1 + k);
- dk_pagetoosmall = False;
- btupdatepage(l);
- if (errstatus > 0) return;
- }
- else {
- for (i = 1 ; i <= DB_ord ; i++)
- pageptr2->itemarray[i+DB_ord-1] = l->itemarray[i-1];
- for (i = r ; i <= pagptr->itemsonpage-1 ; i++)
- pagptr->itemarray[i-1] = pagptr->itemarray[i];
- pageptr2->itemsonpage = DB_ps;
- pagptr->itemsonpage = pagptr->itemsonpage - 1;
- btreturnpage(&l);
- if (errstatus > 0) return;
- dk_pagetoosmall = (bool) (pagptr->itemsonpage < DB_ord);
- }
- btupdatepage(pageptr2);
- if (errstatus > 0) return;
- }
- else {
- lpageref = (r==1)?pagptr->bckwpageref:pagptr->itemarray[r-2].pageref;
- btgetpage(dk_idxf,lpageref,&l);
- if (errstatus > 0) return;
- litem = l->itemsonpage + 1;
- k = (litem - DB_ord)/2;
- if (k > 0) {
- for (i = DB_ord-1 ; i >= 1 ; i--)
- pageptr2->itemarray[i+k-1] = pageptr2->itemarray[i-1];
- pageptr2->itemarray[k-1] = pagptr->itemarray[r-1];
- pageptr2->itemarray[k-1].pageref = pageptr2->bckwpageref;
- litem = litem - k;
- for (i = k-1 ; i >= 1 ; i--)
- pageptr2->itemarray[i-1] = l->itemarray[i+litem-1];
- pageptr2->bckwpageref = l->itemarray[litem-1].pageref;
- pagptr->itemarray[r-1] = l->itemarray[litem-1];
- pagptr->itemarray[r-1].pageref = prpgref2;
- l->itemsonpage = (byte) (litem - 1);
- pageptr2->itemsonpage = (byte) (DB_ord - 1 + k);
- dk_pagetoosmall = False;
- btupdatepage(pageptr2);
- if (errstatus > 0) return;
- }
- else {
- l->itemarray[litem-1] = pagptr->itemarray[r-1];
- l->itemarray[litem-1].pageref = pageptr2->bckwpageref;
- for (i = 1 ; i <= DB_ord-1 ; i++)
- l->itemarray[i+litem-1] = pageptr2->itemarray[i-1];
- l->itemsonpage = DB_ps;
- pagptr->itemsonpage = pagptr->itemsonpage - 1;
- btreturnpage(&pageptr2);
- if (errstatus > 0) return;
- dk_pagetoosmall = (bool) (pagptr->itemsonpage < DB_ord);
- }
- btupdatepage(l);
- if (errstatus > 0) return;
- }
- btupdatepage(pagptr);
- }
-
- void dk_dela(long prpgref2,long k, btpageptr *pagptr, long *prpgref)
- {
- int c;
- long xpageref;
- btpageptr pageptr2;
-
- btgetpage(dk_idxf,prpgref2,&pageptr2);
- if (errstatus > 0) return;
- xpageref = pageptr2->itemarray[pageptr2->itemsonpage-1].pageref;
- if (xpageref != 0) {
- c = pageptr2->itemsonpage;
- dk_dela(xpageref,k,pagptr,prpgref);
- if (dk_pagetoosmall)
- dk_underflow(prpgref2,xpageref,c);
- if (errstatus > 0) return;
- }
- else {
- btgetpage(dk_idxf,*prpgref,pagptr);
- if (errstatus > 0) return;
- pageptr2->itemarray[pageptr2->itemsonpage-1].pageref =
- (*pagptr)->itemarray[(int) k-1].pageref;
- (*pagptr)->itemarray[(int) k-1] =
- pageptr2->itemarray[pageptr2->itemsonpage-1];
- (pageptr2->itemsonpage)--;
- dk_pagetoosmall = (bool) (pageptr2->itemsonpage < DB_ord);
- btupdatepage(*pagptr);
- btupdatepage(pageptr2);
- if (errstatus > 0) return;
- }
- }
-
- void dk_delb(long prpgref)
- {
- long c,i,k,l,r,xpageref;
- btpageptr pagptr;
-
- if (errstatus > 0) return;
- if (prpgref == 0) {
- ok = False;
- dk_pagetoosmall = False;
- }
- else {
- btgetpage(dk_idxf,prpgref,&pagptr);
- if (errstatus > 0) return;
- l = 1;
- r = pagptr->itemsonpage;
- do {
- k = (l + r)/2;
- c = btcompkeys(dk_prockey,pagptr->itemarray[(int) k-1].key,
- *dk_datarecnum,
- pagptr->itemarray[(int) k-1].dataref,
- dk_idxf->allowduplkeys);
- if (c <= 0) r = k - 1;
- if (c >= 0) l = k + 1;
- } while (l <= r);
- xpageref = (r == 0) ? pagptr->bckwpageref : pagptr->itemarray[(int) r-1].pageref;
- if (l - r > 1) {
- *dk_datarecnum = pagptr->itemarray[(int) k-1].dataref;
- if (xpageref == 0) {
- pagptr->itemsonpage = pagptr->itemsonpage - 1;
- dk_pagetoosmall = (bool) (pagptr->itemsonpage < DB_ord);
- for (i=k ; i <= pagptr->itemsonpage ; i++)
- pagptr->itemarray[(int) i-1]=pagptr->itemarray[(int) i];
- btupdatepage(pagptr);
- if (errstatus > 0) return;
- }
- else {
- dk_dela(xpageref,k,&pagptr,&prpgref);
- if (dk_pagetoosmall)
- dk_underflow(prpgref,xpageref,(int) r);
- if (errstatus > 0) return;
- }
- }
- else {
- dk_delb(xpageref);
- if (dk_pagetoosmall)
- dk_underflow(prpgref,xpageref,(int) r);
- if (errstatus > 0) return;
- }
- }
- }
-
- void db_deletekey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- btpageptr pagptr;
-
- if (!vfyidxhdr(idxf)) return;
- dk_idxf = idxf;
- dk_datarecnum = datarecnum;
- dk_prockey = prockey;
- btxkey(prockey,idxf->keyl);
- ok = True;
- dk_delb(idxf->rr);
- if (errstatus > 0) return;
- if (dk_pagetoosmall) {
- btgetpage(idxf,idxf->rr,&pagptr);
- if (errstatus > 0) return;
- if (pagptr->itemsonpage == 0) {
- idxf->rr = pagptr->bckwpageref;
- btreturnpage(&pagptr);
- if (errstatus > 0) return;
- }
- }
- idxf->pp = 0;
- }
-
- void cleanup(void)
- {
- if (shutdown != NULL) (*shutdown)();
- }
-
- bool io_error(int *loops, int wait, bool mustsucceed)
- {
- uchar ch;
- bool abort,ioerr;
- word fatal;
- errorstring emsg;
-
- ioerr = (bool) (errstatus > 0);
- if (ioerr) {
- fatal = errstatus;
- abort = True;
- (*loops)--;
- if ((errstatus == RecLocked) && multiuser) {
- abort = False;
- if (wait > 0) delay(wait);
- if ((*loops == 0) && mustsucceed) {
- gotoxy(1,1); clreol();
- cwrite(LSC_UnexpectedLockedIndex);
- do {
- ch = getkey();
- if ((ch >= 'a') && (ch <= 'z')) ch -= 'a'-'A';
- } while (!((ch == _Retry) || (ch == _Abort)));
- gotoxy(1,1);
- clreol();
- if (ch == _Retry)
- *loops = idx_retries;
- else
- abort = True;
- }
- }
- if (*loops >= 0) resetstatus();
- if (abort) {
- if ((!recursive) && (shutdown != NULL)) {
- recursive = True;
- cleanup();
- }
- gotoxy(1,1); clreol();
- cwrite(LSC_FatalIO);
- sprintf(emsg,"%u",fatal);
- cwrite(emsg);
- gotoxy(1,2); clreol();
- cwrite(ioerrstr(emsg,fatal));
- gotoxy(1,3); clreol();
- cwrite(LSC_PressAnyKey);
- getkey();
- exit(0);
- }
- }
- return (ioerr);
- }
-
- void addkey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- _loop_count = idx_retries;
- do
- db_addkey(idxf,datarecnum,prockey);
- while (io_error(&_loop_count,0,True));
- if (ok && flush_if)
- flushindex(idxf);
- }
-
- void addrec(datafile *datf, long *r, void *buffer)
- {
- _loop_count = retries;
- do
- db_addrec(datf,r,buffer);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- if (flush_df)
- flushfile(datf);
- }
-
- void clearkey(indexfile *idxf)
- {
- db_clearkey(idxf);
- }
-
- void closefile(datafile *datf)
- {
- _loop_count = retries;
- do
- db_closefile(datf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void closeindex(indexfile *idxf)
- {
- _loop_count = retries;
- do
- db_closeindex(idxf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void deletekey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- _loop_count = idx_retries;
- do
- db_deletekey(idxf,datarecnum,prockey);
- while (io_error(&_loop_count,0,True));
- if (ok && flush_if)
- flushindex(idxf);
- }
-
- void deleterec(datafile *datf, long r)
- {
- if (r==0) { btstatus = 2000; btiocheck(datf,r); }
- _loop_count = retries;
- do
- db_deleterec(datf,r);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- if (flush_df)
- flushfile(datf);
- }
-
- void erasefile(datafile *datf)
- {
- _loop_count = retries;
- do
- db_erasefile(datf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void eraseindex(indexfile *idxf)
- {
- _loop_count = retries;
- do
- db_eraseindex(idxf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void flushfile(datafile *datf)
- {
- _loop_count = retries;
- do
- db_flushfile(datf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void flushindex(indexfile *idxf)
- {
- _loop_count = retries;
- do
- db_flushindex(idxf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- long filelen(datafile *datf)
- {
- long fl;
-
- _loop_count = retries;
- do
- fl = db_filelen(datf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- return (fl);
- }
-
- void findkey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- _loop_count = idx_retries;
- do
- db_findkey(idxf,datarecnum,prockey);
- while (io_error(&_loop_count,0,True));
- }
-
- void getlockedrec(datafile *datf, long r, void *buffer)
- {
- _loop_count = retries;
- do
- db_getlockedrec(datf,r,buffer);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void getrec(datafile *datf, long r, void *buffer)
- {
- _loop_count = retries;
- do {
- db_getrec(datf,r,buffer);
- if (multiuser && (errstatus == RecLocked)) {
- resetstatus();
- db_getlockedrec(datf,r,buffer);
- }
- else
- lockget = False;
- } while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void makefile(datafile *datf, strptr fname, word reclen)
- {
- if (reclen > DB_mxdrs)
- reclen = DB_mxdrs;
- else
- if (reclen < DB_mdrs)
- reclen = DB_mdrs;
- _loop_count = retries;
- do
- db_makefile(datf,fname,reclen);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void makeindex(indexfile *idxf, strptr fname, byte keylen, byte s)
- {
- if (keylen > DB_Klen)
- keylen = DB_Klen;
- _loop_count = retries;
- do
- db_makeindex(idxf,fname,keylen,s);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void nextkey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- _loop_count = idx_retries;
- do
- db_nextkey(idxf,datarecnum,prockey);
- while (io_error(&_loop_count,0,True));
- }
-
- void openfile(datafile *datf, strptr fname, word reclen)
- {
- if (reclen > DB_mxdrs)
- reclen = DB_mxdrs;
- else
- if (reclen < DB_mdrs)
- reclen = DB_mdrs;
- _loop_count = retries;
- do
- db_openfile(datf,fname,reclen);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void openindex(indexfile *idxf, strptr fname, byte keylen, byte s)
- {
- if (keylen > DB_Klen)
- keylen = DB_Klen;
- _loop_count = retries;
- do
- db_openindex(idxf,fname,keylen,s);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- }
-
- void prevkey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- _loop_count = idx_retries;
- do
- db_prevkey(idxf,datarecnum,prockey);
- while (io_error(&_loop_count,0,True));
- }
-
- void putrec(datafile *datf, long r, void *buffer)
- {
- if (r==0) { btstatus = 2000; btiocheck(datf,r); }
- _loop_count = retries;
- do
- db_putrec(datf,r,buffer);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- if (flush_df)
- flushfile(datf);
- }
-
- void searchkey(indexfile *idxf, long *datarecnum, void *prockey)
- {
- _loop_count = idx_retries;
- do
- db_search(idxf,datarecnum,prockey);
- while (io_error(&_loop_count,0,True));
- }
-
- long usedrecs(datafile *datf)
- {
- long ur;
-
- _loop_count = retries;
- do
- ur = db_usedrecs(datf);
- while (io_error(&_loop_count,0,True) && (_loop_count > 0));
- return (ur);
- }
-
- int lock_datf(datafile *datf, long rno, byte lck)
- {
- int fval;
- splitlong start,range;
- union REGS regs;
-
- fval = 0;
- if (multiuser) {
- regs.h.ah = 0x5C;
- if (rno >= 0) {
- range.l = 4;
- start.l = rno * datf->itemsize;
- }
- else {
- range.l = datf->itemsize;
- start.l = 0;
- rno = 0;
- }
- regs.h.al = lck;
- regs.x.bx = datf->f.handle;
- regs.x.cx = start.w.h;
- regs.x.dx = start.w.l;
- regs.x.si = range.w.h;
- regs.x.di = range.w.l;
- intdos(®s,®s);
- if (regs.x.cflag)
- fval = regs.x.ax;
- if (fval == 1) fval = 0;
- else {
- if (lck == Lock) {
- db_getrec(datf,rno,btrecbuf);
- if (errstatus == 100) {
- fval = lock_datf(datf,rno,UnLock);
- fval = -1;
- errstatus = 0;
- btstatus = 0;
- }
- }
- }
- }
- return (fval);
- }
-
- int lock_indexf(indexfile *indexf, long rno, byte lck)
- {
- int fval;
-
- fval = 0;
- if (multiuser) {
- rno = -1;
- fval = lock_datf(&indexf->dataf,rno,lck);
- }
- return (fval);
- }
-
- void resetstatus(void)
- {
- errstatus = 0;
- btstatus = 0;
- }
-
- void unit_initindex(void)
- {
- int i;
-
- btrecbuf = (btrecordbufptr) db_malloc(sizeof(btrecordbuffer));
- btpagestk = (btpagestackptr) db_malloc(sizeof(btpagestack));
- btpgmap = (btpagemapptr) db_malloc(sizeof(btpagemap));
- memset(btpagestk,0,sizeof(btpagestack));
- for (i = 1 ; i <= DB_pstack ; i++)
- (*btpgmap)[i-1] = i;
- }
-
- void initindex(void)
- {
- }
-
- /********************** UNIT INITIALIZATION/EXIT CODE *********************/
-
- void db_tree_init(void)
- {
- if (!initialized) {
- initialized = True;
- db_heap_init();
- db_key_init();
- ok = True;
- btstatus = 0;
- errstatus = 0;
- lockget = False;
- recursive = False;
- shutdown = NULL;
- retries = 0;
- idx_retries = 1000;
- unit_initindex();
- }
- }
-
- /**************************** END OF DB_TREE.C ****************************/
-